package com.jfunit.java.helper;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfunit.java.annotation.Bean;
import com.jfunit.java.annotation.Controller;
import com.jfunit.java.annotation.Service;
import com.jfunit.java.util.ClassUtil;

/**
 * 类操作助手类
 * @author Administrator
 *
 */
public final class ClassHelper {
    private final static Logger LOGGER = LoggerFactory.getLogger(ClassHelper.class);
    
    //定义类集合，用于存放所有加载的类
    private static final Set<Class<?>> CLASS_SET;
    
    static{
        String basePackage = ConfigHelper.getAppBasePackage();
        CLASS_SET = ClassUtil.getClassSet(basePackage);
        System.out.println("CLASS_SET:"+CLASS_SET);
    }
    
    /**
     * 获取应用包名下所有的类
     * @return
     */
    public static Set<Class<?>> getClassSet(){
        return CLASS_SET;
    }
    
    /**
     * 获取应用包名下所有Service类
     * @return
     */
    public static Set<Class<?>> getServiceClassSet(){
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Service.class)) {// 是否存在 services注解
                classSet.add(cls);
            }
        }
        return classSet;
    }
    
    /**
     * 获取应用包名下所有Controller类
     * @return
     */
    public static Set<Class<?>> getControllerClassSet(){
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Controller.class)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }
    
    /**
     * 获取应用包名下所有需要 IOC 容器管理的 Bean 类
     * @return
     */
    public static Set<Class<?>> getIocBeanClassSet(){
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(Bean.class)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }
    
    /**
     * 获取应用包名下所有Bean类，包含Service,Controller类
     * @return
     */
    public static Set<Class<?>> getBeanClassSet(){
        Set<Class<?>> beanClassSet = new HashSet<Class<?>>();
        beanClassSet.addAll(getServiceClassSet());
        beanClassSet.addAll(getControllerClassSet());
        beanClassSet.addAll(getIocBeanClassSet());//定义需要 IOC 容器管理的 Bean 类
        return beanClassSet;
    }
    
    /**
     * 获取应用包名下某父类（或接口）的所有子类（或实现类）
     * @param superClass
     * @return
     */
    public static Set<Class<?>> getClassSetBySupper(Class<?> superClass){
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for (Class<?> cls : CLASS_SET) {
            //判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同，或是否是其超类或超接口。 并且不等于自己
            //表示 superClass 是 cls的父类或接口
            if (superClass.isAssignableFrom(cls) && !superClass.equals(cls)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }
    
    /**
     * 获取应用包名下带有某注解的所有类
     * @param annotationClass
     * @return
     */
    public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotationClass){
        Set<Class<?>> classSet = new HashSet<Class<?>>();
        for (Class<?> cls : CLASS_SET) {
            if (cls.isAnnotationPresent(annotationClass)) {
                classSet.add(cls);
            }
        }
        return classSet;
    }
    
    
    
}
